package parser

import (
	"shenfu.com/stone/ast"
	"shenfu.com/stone/token"
)

const (
	OP_RIGHT = iota
	OP_LEFT
)

type ASTree = ast.ASTNode
type Lexer = token.Lexer

type Element interface {
	Match(lexer *Lexer) (bool, error)
	Parse(lexer *Lexer, res []ASTree) error
}

type Parser struct {
	elements []Element
}

type MakeFunc func(results []ASTree) ASTree

type Tree struct {
	parser *Parser
}

/**
 * *Tree实现了Element， 但是Tree没有，因为这里定义的接收器是指针类型
 * 所以没法 将Tree类型赋值给Element， 只能是*Tree
 */
func (t *Tree) Match(lexer *Lexer) (bool, error) {
	return t.parser.Match(lexer)
}

func (t *Tree) Parse(lexer *Lexer, res []ASTree) error {
	tree, err := t.parser.Parse(lexer)
	if err != nil {
		return err
	}
	//TODO 如何修改res
	res = append(res, tree)
	return nil
}

type OrTree struct {
	prasers []*Parser
}

func (t *OrTree) choose(lexer *Lexer) *Parser {
	for _, parser := range t.prasers {
		match, _ := parser.Match(lexer)
		if match {
			return parser
		}
	}
	return nil
}

func (t *OrTree) Match(lexer *Lexer) (bool, error) {
	parser := t.choose(lexer)
	return parser != nil, nil
}

var DefaultMake MakeFunc = func(results []ASTree) ASTree {
	len := len(results)
	if len == 1 {
		return results[0]
	} else {
		return nil
	}
}

func (p *Parser) Parse(lexer *Lexer) (ASTree, error) {
	var results []ASTree = make([]ASTree, 0)
	for _, e := range p.elements {
		err := e.Parse(lexer, results)
		if err != nil {
			return nil, err
		}
	}
	astree := DefaultMake(results)
	return astree, nil
}

func (p *Parser) Match(lexer *Lexer) (bool, error) {
	if len(p.elements) == 1 {
		return true, nil
	} else {
		e := p.elements[1]
		return e.Match(lexer)
	}
}

func NewParser() *Parser {
	return &Parser{}
}

func (p *Parser) Ast(ap *Parser) *Parser {
	tree := Tree{
		parser: ap,
	}
	//append之后返回了一个新的切片
	p.elements = append(p.elements, &tree)
	return p
}
